#ifndef LOGGER_H
#define LOGGER_H

bool PRINTLOG = 1;
bool RECORDLOG = 1;
#include <system_error>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <mutex>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <unordered_map>
#include <algorithm>
#include <stdexcept>
#include <queue>
#include <thread>
#include <condition_variable>
#include <atomic>

// 日志级别枚举（规范命名）
enum class LogLevel {
	DEBUG,
	INFO,
	WARNING,
	ERROR_LEVEL,  // 修正枚举名称
	CRITICAL
};

// 重载比较运算符用于日志级别过滤
inline bool operator<(LogLevel lhs, LogLevel rhs) {
	return static_cast<int>(lhs) < static_cast<int>(rhs);
}

inline bool operator>=(LogLevel lhs, LogLevel rhs) {
	return static_cast<int>(lhs) >= static_cast<int>(rhs);
}

// 日志条目结构体
struct LogEntry {
	int id;
	std::string speaker;
	std::string label;
	std::string message;
	LogLevel level;
	std::chrono::system_clock::time_point timestamp;
	std::unordered_map<std::string, std::string> tags;

	// 新增：错误码支持
	int error_code = 0;
};

class Logger {
	private:
		std::string name_;
		std::vector<LogEntry> entries_;
		std::unordered_map<int, LogEntry*> entries_map_;
		mutable std::mutex mutex_;
		int next_id_ = 1;
		bool enable_console_ = false;
		std::ofstream log_file_;
		size_t max_entries_ = 10000;
		bool use_utc_ = false;

		// 扩展功能1: 最小日志级别过滤
		LogLevel min_level_ = LogLevel::DEBUG;

		// 扩展功能2: 异步日志写入
		std::queue<LogEntry> async_queue_;
		std::thread async_thread_;
		std::condition_variable async_cv_;
		std::atomic<bool> async_stop_{false};
		bool async_enabled_ = false;

		// 扩展功能3: 日志文件滚动
		size_t max_file_size_ = 10 * 1024 * 1024; // 10MB默认大小
		int max_backup_files_ = 5;
		std::string log_file_path_;

		// 扩展功能5: 更灵活的格式化
		std::string format_pattern_ = u8"在时间[{time}], 日志器[{logger}]输出 汇报人:{speaker} [{label}] {level} {tags}内容:{message}";

		// 新增：扩展功能4 - 日志加密
		bool enable_encryption_ = false;
		std::string encryption_key_ = "default_key";

		// 新增：批量写入参数
		size_t batch_size_ = 10;  // 批量写入的日志数量
		std::vector<LogEntry> batch_buffer_;  // 批量写入缓冲区

		// 新增：条件日志功能支持
		std::function<bool(const LogEntry&)> condition_predicate_ = nullptr;

		// 新增：日志聚合器支持
		static std::vector<Logger*> all_loggers_;
		static std::mutex loggers_mutex_;

		// 格式化时间戳（支持UTC）
		std::string formatTime(const std::chrono::system_clock::time_point& tp) const {
			auto time = std::chrono::system_clock::to_time_t(tp);
			std::tm tm;

			if (use_utc_) {
#if defined(_WIN32)
				gmtime_s(&tm, &time);
#else
				gmtime_r(&time, &tm);
#endif
			} else {
#if defined(_WIN32)
				localtime_s(&tm, &time);
#else
				localtime_r(&time, &tm);
#endif
			}

			std::stringstream ss;
			ss << std::put_time(&tm, "%Y/%m/%d %H:%M:%S");
			// 新增：毫秒级时间精度
			auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
			              tp.time_since_epoch()).count() % 1000;
			ss << "." << std::setw(3) << std::setfill('0') << ms;

			if (use_utc_) ss << " UTC";
			return ss.str();
		}

		// 格式化标签集（修复多余字符）
		std::string formatTags(const std::unordered_map<std::string, std::string>& tags) const {
			if (tags.empty()) return "";

			std::stringstream ss;
			for (const auto& [key, value] : tags) {
				ss << " " << key << "=" << value;
			}
			return ss.str();
		}

		// 级别转中文（使用Unicode转义）
		std::string levelToString(LogLevel level) const {
			switch (level) {
				case LogLevel::DEBUG:
					return u8"[调试]";
				case LogLevel::INFO:
					return u8"[信息]";
				case LogLevel::WARNING:
					return u8"[警告]";
				case LogLevel::ERROR_LEVEL:
					return u8"[错误]";
				case LogLevel::CRITICAL:
					return u8"[紧急]";
				default:
					return u8"[未知]";
			}
		}

		// 新增：简单的加密方法（生产环境应使用更安全的加密算法）
		std::string encrypt(const std::string& data) const {
			if (!enable_encryption_) return data;

			std::string result = data;
			for (size_t i = 0; i < result.size(); ++i) {
				result[i] ^= encryption_key_[i % encryption_key_.size()];
			}
			return result;
		}

		// 新增：简单的解密方法
		std::string decrypt(const std::string& data) const {
			return encrypt(data); // XOR加密是对称的
		}

		// 检查并执行文件滚动
		void checkFileRotation() {
			if (log_file_.is_open() && max_file_size_ > 0) {
				auto current_size = log_file_.tellp();
				if (current_size >= static_cast<std::streampos>(max_file_size_)) {
					log_file_.close();

					// 重命名现有备份文件
					for (int i = max_backup_files_ - 1; i > 0; --i) {
						std::string old_name = log_file_path_ + "." + std::to_string(i);
						std::string new_name = log_file_path_ + "." + std::to_string(i + 1);

						std::ifstream old_file(old_name);
						if (old_file.good()) {
							old_file.close();
							std::remove(new_name.c_str());
							std::rename(old_name.c_str(), new_name.c_str());
						}
					}

					// 重命名当前文件
					std::string first_backup = log_file_path_ + ".1";
					std::remove(first_backup.c_str());
					std::rename(log_file_path_.c_str(), first_backup.c_str());

					// 重新打开日志文件
					log_file_.open(log_file_path_, std::ios::app);
					if (!log_file_.is_open()) {
						throw std::runtime_error(u8"无法重新打开日志文件: " + log_file_path_);
					}
				}
			}
		}

		// 写入文件（含异常处理和文件滚动检查）
		void writeToFile(const LogEntry& entry) {
			// 1. 检查文件状态 - 基础且必要
			if (!log_file_.is_open()) {
				std::cerr << u8"错误：日志文件未打开，无法写入日志。" << std::endl;
				return;
			}

			try {
				// 2. 检查文件滚动
				checkFileRotation();

				// 3. 格式化日志条目
				std::string formatted = formatEntry(entry);

				// 4. 加密处理 (如果启用)
				if (enable_encryption_) {
					formatted = encrypt(formatted); // 确保你的encrypt函数是异常安全的
				}

				// 5. 执行写入操作
				log_file_ << formatted << "\n";

				// 6. 【性能优化】谨慎使用flush：权衡数据安全与性能
				// 如果您的日志对实时性要求极高，不能容忍任何丢失，请保留flush。
				// 否则，可以考虑注释掉flush，依靠系统缓冲区定时写入，或者批量写入后统一flush。
				// log_file_.flush();

				// 7. 【重要增强】检查写入操作是否成功！
				if (log_file_.fail()) {
					throw std::ios_base::failure(u8"文件流写入操作失败。");
				}

			} catch (const std::ios_base::failure& e) {
				// 专门捕获文件I/O操作相关的异常
				std::error_code ec = std::make_error_code(std::io_errc::stream);
				std::cerr << u8"文件I/O错误: " << e.what() << u8", 错误码: " << ec.message() << std::endl;
				// 此处可添加更复杂的错误处理逻辑，如尝试重新打开文件
			} catch (const std::exception& e) {
				// 捕获其他标准异常（例如加密可能抛出的异常）
				std::cerr << u8"写入日志时发生标准异常: " << e.what() << std::endl;
			} catch (...) {
				// 保留捕获所有异常，作为最后的安全网
				std::cerr << u8"写入日志时发生未知异常。" << std::endl;
			}
		}

		// 新增：批量写入文件
		void batchWriteToFile() {
			if (batch_buffer_.empty() || !log_file_.is_open()) return;

			try {
				checkFileRotation();

				for (const auto& entry : batch_buffer_) {
					std::string formatted = formatEntry(entry);
					if (enable_encryption_) {
						formatted = encrypt(formatted);
					}
					log_file_ << formatted << "\n";
				}

				log_file_.flush();
				batch_buffer_.clear();
			} catch (...) {
				std::cerr << u8"批量文件写入失败" << std::endl;
			}
		}

		// 异步工作线程
		void asyncWorker() {
			std::queue<LogEntry> local_queue;
			while (!async_stop_.load() || !local_queue.empty()) {
				{
					std::unique_lock<std::mutex> lock(mutex_);
					async_cv_.wait(lock, [this] {
						return !async_queue_.empty() || async_stop_.load();
					});
					if (async_stop_.load() && async_queue_.empty()) break;
					std::swap(local_queue, async_queue_);
				} // 释放锁

				while (!local_queue.empty()) {
					auto& entry = local_queue.front();
					if (enable_console_) {
						std::cout << formatEntry(entry) << std::endl;
					}
					writeToFile(entry);
					local_queue.pop();
				}
			}
		}

		// 替换字符串中的所有匹配项
		static void replaceAll(std::string& str, const std::string& from, const std::string& to) {
			size_t start_pos = 0;
			while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
				str.replace(start_pos, from.length(), to);
				start_pos += to.length();
			}
		}

	public:
		size_t getEntryCount() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return entries_.size();
		}

		// 获取指定索引的日志条目（用于测试验证，使用需谨慎）
		const LogEntry& getEntry(size_t index) const {
			std::lock_guard<std::mutex> lock(mutex_);
			if (index >= entries_.size()) {
				throw std::out_of_range("Index out of range");
			}
			return entries_[index];
		}

		// 获取最近一条日志的消息内容（简便的测试方法）
		std::string getLastLogMessage() const {
			std::lock_guard<std::mutex> lock(mutex_);
			if (entries_.empty()) {
				return "";
			}
			return entries_.back().message;
		}
		// 构造函数（强制名称参数）
		explicit Logger(const std::string& name, const std::string& filename = "")
			: name_(name), log_file_path_(filename) {
			// 新增：注册到全局日志器列表
			std::lock_guard<std::mutex> lock(loggers_mutex_);
			all_loggers_.push_back(this);

			if (!filename.empty()) {
				log_file_.open(filename, std::ios::app);
				if (!log_file_.is_open()) {
					throw std::runtime_error(u8"无法打开日志文件: " + filename);
				}
			}
		}

		~Logger() {
			// 新增：从全局日志器列表中移除
			std::lock_guard<std::mutex> lock(loggers_mutex_);
			all_loggers_.erase(
			    std::remove(all_loggers_.begin(), all_loggers_.end(), this),
			    all_loggers_.end());

			// 处理剩余的批量日志
			if (!batch_buffer_.empty()) {
				batchWriteToFile();
			}

			// 停止异步线程
			if (async_enabled_) {
				async_stop_.store(true);
				async_cv_.notify_all();
				if (async_thread_.joinable()) {
					async_thread_.join();
				}
			}

			// 关闭文件
			if (log_file_.is_open()) {
				log_file_.close();
			}
		}

		// 核心日志方法（线程安全）
		void log(const std::string& speaker,
		         const std::string& label,
		         const std::string& message,
		         LogLevel level = LogLevel::INFO,
		         const std::unordered_map<std::string, std::string>& tags = {},
		         int error_code = 0) {
			// 新增：条件日志检查
			if (condition_predicate_) {
				LogEntry temp_entry{0, speaker, label, message, level,
				                    std::chrono::system_clock::now(), tags};
				temp_entry.error_code = error_code;
				if (!condition_predicate_(temp_entry)) {
					return;
				}
			}

			// 扩展功能1: 检查日志级别过滤
			if (level < min_level_) return;

			std::lock_guard<std::mutex> lock(mutex_);

			// 自动清理旧日志
			if (RECORDLOG == 1) {
				if (entries_.size() >= max_entries_) {
					size_t remove_count = entries_.size() - max_entries_ + 1;
					entries_.erase(entries_.begin(), entries_.begin() + remove_count);
					entries_map_.clear();
					for (auto& entry : entries_) {
						entries_map_[entry.id] = &entry;
					}
				}

				// 添加新条目
				entries_.emplace_back(LogEntry{
					next_id_,
					speaker,
					label,
					message,
					level,
					std::chrono::system_clock::now(),
					tags
				});
				entries_.back().error_code = error_code;
				entries_map_[next_id_++] = &entries_.back();

				// 扩展功能2: 异步处理
				if (async_enabled_) {
					async_queue_.push(entries_.back());
					async_cv_.notify_one();
				} else {
					// 同步处理
					if (enable_console_) {
						std::cout << formatEntry(entries_.back()) << std::endl;
					}
					// 新增：支持批量写入
					if (batch_size_ > 1) {
						batch_buffer_.push_back(entries_.back());
						if (batch_buffer_.size() >= batch_size_) {
							batchWriteToFile();
						}
					} else {
						writeToFile(entries_.back());
					}
				}
			}
		}

		// 打印全部日志
		void printAll() const {
			if (PRINTLOG == 1) {
				std::lock_guard<std::mutex> lock(mutex_);
				for (const auto& entry : entries_) {
					std::cout << formatEntry(entry) << std::endl;
				}
			}
		}

		// 打印最近若干条
		void printSome(int num) const {
			if (PRINTLOG == 1) {
				std::lock_guard<std::mutex> lock(mutex_);
				num = std::max(0, num);
				const size_t start_idx = entries_.size() > static_cast<size_t>(num)
				                         ? entries_.size() - num
				                         : 0;

				for (size_t i = start_idx; i < entries_.size(); ++i) {
					std::cout << formatEntry(entries_[i]) << std::endl;
				}
			}
		}

		// 按ID打印（O(1)查找）
		void printById(int id) const {
			if (PRINTLOG == 1) {
				std::lock_guard<std::mutex> lock(mutex_);
				auto it = entries_map_.find(id);
				if (it != entries_map_.end()) {
					std::cout << formatEntry(*(it->second)) << std::endl;
				} else {
					std::cerr << u8"※ 未找到ID为 " << id << u8" 的日志记录" << std::endl;
				}
			}
		}

		// 按标签模糊查询
		void printByLabel(const std::string& label) const {
			std::lock_guard<std::mutex> lock(mutex_);
			if (PRINTLOG == 1) {
				bool found = false;
				for (const auto& entry : entries_) {
					if (entry.label.find(label) != std::string::npos) {
						std::cout << formatEntry(entry) << std::endl;
						found = true;
					}
				}
				if (!found) {
					std::cerr << u8"※ 未找到包含标签 '" << label << u8"' 的日志" << std::endl;
				}
			}
		}

		// 新增：按错误码查询
		void printByErrorCode(int error_code) const {
			std::lock_guard<std::mutex> lock(mutex_);
			if (PRINTLOG == 1) {
				bool found = false;
				for (const auto& entry : entries_) {
					if (entry.error_code == error_code) {
						std::cout << formatEntry(entry) << std::endl;
						found = true;
					}
				}
				if (!found) {
					std::cerr << u8"※ 未找到错误码为 " << error_code << u8" 的日志" << std::endl;
				}
			}
		}

// 扩展功能1: 设置最小日志级别
		void setminLevel(LogLevel level) {
			std::lock_guard<std::mutex> lock(mutex_);
			min_level_ = level;
		}

// 扩展功能1: 获取当前最小日志级别
		LogLevel getMinLevel() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return min_level_;
		}
		// 按级别过滤
		void printByLevel(LogLevel level) const {
			std::lock_guard<std::mutex> lock(mutex_);
			if (PRINTLOG == 1) {
				bool found = false;
				for (const auto& entry : entries_) {
					if (entry.level == level) {
						std::cout << formatEntry(entry) << std::endl;
						found = true;
					}
				}
				if (!found) {
					std::cerr << u8"※ 未找到 " << levelToString(level) << u8" 级别的日志" << std::endl;
				}
			}
		}

		// 格式化条目（扩展功能5: 支持自定义格式化）
		std::string formatEntry(const LogEntry& entry) const {
			if (PRINTLOG == 0) return "";

			std::string result = format_pattern_;

			// 替换各种占位符
			replaceAll(result, "{time}", formatTime(entry.timestamp));
			replaceAll(result, "{logger}", name_);
			replaceAll(result, "{speaker}", entry.speaker);
			replaceAll(result, "{label}", entry.label);
			replaceAll(result, "{level}", levelToString(entry.level));
			replaceAll(result, "{tags}", formatTags(entry.tags));
			replaceAll(result, "{message}", entry.message);
			replaceAll(result, "{id}", std::to_string(entry.id));
			// 新增：错误码占位符
			replaceAll(result, "{error_code}", std::to_string(entry.error_code));

			return result;
		}

		// 控制台输出开关
		void setConsoleOutput(bool enable) {
			std::lock_guard<std::mutex> lock(mutex_);
			enable_console_ = enable;
		}

		// 设置最大存储条目
		void setMaxEntries(size_t max) {
			std::lock_guard<std::mutex> lock(mutex_);
			max_entries_ = max;
		}

		// 设置UTC时间模式
		void setUseUTC(bool utc) {
			std::lock_guard<std::mutex> lock(mutex_);
			use_utc_ = utc;
		}

		// 扩展功能1: 设置最小日志级别
		void setMinLevel(LogLevel level) {
			std::lock_guard<std::mutex> lock(mutex_);
			min_level_ = level;
		}

		// 扩展功能1: 获取当前最小日志级别
		LogLevel getMinLevel() {
			std::lock_guard<std::mutex> lock(mutex_);
			return min_level_;
		}

		// 扩展功能2: 启用/禁用异步日志
		void enableAsync(bool enable) {
			std::lock_guard<std::mutex> lock(mutex_);
			if (enable && !async_enabled_) {
				async_enabled_ = true;
				async_stop_.store(false);
				async_thread_ = std::thread(&Logger::asyncWorker, this);
			} else if (!enable && async_enabled_) {
				async_enabled_ = false;
				async_stop_.store(true);
				async_cv_.notify_all();
				if (async_thread_.joinable()) {
					async_thread_.join();
				}
			}
		}

		// 扩展功能2: 检查是否启用异步日志
		bool isAsyncEnabled() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return async_enabled_;
		}

		// 扩展功能3: 设置文件滚动参数
		void setFileRotation(size_t max_size, int max_backups) {
			std::lock_guard<std::mutex> lock(mutex_);
			max_file_size_ = max_size;
			max_backup_files_ = max_backups;
		}

		// 扩展功能3: 获取当前文件滚动设置
		std::pair<size_t, int> getFileRotation() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return {max_file_size_, max_backup_files_};
		}

		// 扩展功能5: 设置自定义格式
		void setFormatPattern(const std::string& pattern) {
			std::lock_guard<std::mutex> lock(mutex_);
			format_pattern_ = pattern;
		}

		// 扩展功能5: 获取当前格式模式
		std::string getFormatPattern() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return format_pattern_;
		}

		// 新增：扩展功能4 - 启用/禁用日志加密
		void enableEncryption(bool enable, const std::string& key = "") {
			std::lock_guard<std::mutex> lock(mutex_);
			enable_encryption_ = enable;
			if (!key.empty()) {
				encryption_key_ = key;
			}
		}

		// 新增：检查是否启用加密
		bool isEncryptionEnabled() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return enable_encryption_;
		}

		// 新增：设置批量写入参数
		void setBatchSize(size_t size) {
			std::lock_guard<std::mutex> lock(mutex_);
			batch_size_ = size > 0 ? size : 1;
		}

		// 新增：获取批量写入参数
		size_t getBatchSize() const {
			std::lock_guard<std::mutex> lock(mutex_);
			return batch_size_;
		}

		// 新增：设置条件日志谓词
		void setConditionPredicate(std::function<bool(const LogEntry&)> predicate) {
			std::lock_guard<std::mutex> lock(mutex_);
			condition_predicate_ = predicate;
		}

		// 新增：清除条件日志谓词
		void clearConditionPredicate() {
			std::lock_guard<std::mutex> lock(mutex_);
			condition_predicate_ = nullptr;
		}

		// 新增：日志聚合功能 - 全局记录日志到所有日志器
		static void logToAll(const std::string& speaker,
		                     const std::string& label,
		                     const std::string& message,
		                     LogLevel level = LogLevel::INFO,
		                     const std::unordered_map<std::string, std::string>& tags = {}) {
			std::lock_guard<std::mutex> lock(loggers_mutex_);
			for (auto logger : all_loggers_) {
				logger->log(speaker, label, message, level, tags);
			}
		}

		// 禁用拷贝
		Logger(const Logger&) = delete;
		Logger& operator=(const Logger&) = delete;
};

// 静态成员初始化
std::vector<Logger*> Logger::all_loggers_;
std::mutex Logger::loggers_mutex_;

// 全局实例声明
Logger DefaultLog("DefaultLog", "log.txt");

// 新增：便捷日志宏
#define LOG_DEBUG(speaker, label, message, ...) DefaultLog.log(speaker, label, message, LogLevel::DEBUG, ##__VA_ARGS__)
#define LOG_INFO(speaker, label, message, ...) DefaultLog.log(speaker, label, message, LogLevel::INFO, ##__VA_ARGS__)
#define LOG_WARNING(speaker, label, message, ...) DefaultLog.log(speaker, label, message, LogLevel::WARNING, ##__VA_ARGS__)
#define LOG_ERROR(speaker, label, message, error_code, ...) DefaultLog.log(speaker, label, message, LogLevel::ERROR_LEVEL, ##__VA_ARGS__, error_code)
#define LOG_CRITICAL(speaker, label, message, error_code, ...) DefaultLog.log(speaker, label, message, LogLevel::CRITICAL, ##__VA_ARGS__, error_code)

#endif // LOGGER_H